package com.hyfrogx.modules.manage.service.task.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyfrogx.common.exception.MyException;
import com.hyfrogx.common.exception.ServiceException;
import com.hyfrogx.modules.app.entity.User;
import com.hyfrogx.modules.app.form.Task.TaskForm;
import com.hyfrogx.modules.app.service.UserService;
import com.hyfrogx.modules.app.utils.FrogxTaskCode;
import com.hyfrogx.modules.manage.dao.task.TaskDao;
import com.hyfrogx.modules.manage.entity.coin.CoinDetailEntity;
import com.hyfrogx.modules.manage.entity.task.TaskEntity;
import com.hyfrogx.modules.manage.entity.task.TaskRewardEntity;
import com.hyfrogx.modules.manage.entity.task.TaskUserInfoEntity;
import com.hyfrogx.modules.manage.service.task.TaskRewardService;
import com.hyfrogx.modules.manage.service.task.TaskService;
import com.hyfrogx.modules.manage.service.task.TaskUserInfoService;
import com.hyfrogx.modules.manage.util.ScoreCoinUtils;
import com.hyfrogx.modules.manage.util.TaskRewardUtils;
import com.hyfrogx.modules.operation.service.umeng.UmengService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

/**
 * @author 罗春杰-技术部
 */
@Service
public class TaskServiceImpl extends ServiceImpl<TaskDao, TaskEntity> implements TaskService {
    @Autowired
    UserService userService;
    @Autowired
    TaskUserInfoService taskUserInfoService;
    @Autowired
    TaskRewardService taskRewardService;
    @Lazy
    @Autowired
    UmengService umengService;


    /**
     * 分享课程、快讯、资讯、直播、每日任务、学习课程、观看直播    任务
     *
     * @param
     * @throws Exception
     */
    public void taskShare(TaskForm form) throws Exception {
        try {
            // 计算当前时间的年月日
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String toDate = sdf.format(new Date());
            User user = userService.getById(form.getUid());
            // 1.查该任务能完成几次
            TaskEntity hyTask = this.baseMapper.selectOne(new QueryWrapper<TaskEntity>()
                    .eq("code", form.getCode()).eq("status", 1));
            if (ObjectUtil.isNotEmpty(hyTask)) {
                List<TaskUserInfoEntity> listTaskInfoDaily = taskUserInfoService.list(new QueryWrapper<TaskUserInfoEntity>()
                        .eq("task_code", form.getCode()).eq("date", toDate).eq("uid", form.getUid()));
                if (listTaskInfoDaily.size() < hyTask.getTotal()) {
                    //获取奖励
                    Map<String, Integer> rewardByCode = this.getRewardByCode(form.getCode(), form.getUid(), null);
                    //发送积分系统和推送
                    this.sendCoin(user,hyTask,rewardByCode);
                    if(form.getCode() == FrogxTaskCode.TaskCode.WATCH_COURSE || form.getCode() == FrogxTaskCode.TaskCode.WATCH_LIVE){
                        //保存任务记录
                        this.updateInfo(form.getCode(), form.getSid(), user,rewardByCode);
                    }else {
                        this.updateInfo(form.getCode(), null, user,rewardByCode);
                    }
                }
            }else {
                throw new Exception("任务找不到/未上架");
            }
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }


    }

    /**
     * 评论课程、文章、阅读资讯    任务
     *
     * @param uid
     * @param code
     * @param sid
     * @throws Exception
     */
    public void taskRemark(Long uid, Integer code, Integer sid) throws Exception {
        try {
            // 计算当前时间的年月日
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String toDate = sdf.format(new Date());
            User user = userService.getById(uid);
            // 1.查该任务能完成几次
            TaskEntity hyTask = this.baseMapper.selectOne(new QueryWrapper<TaskEntity>()
                    .eq("code", code).eq("status", 1));
            if (ObjectUtil.isNotEmpty(hyTask)) {
                Boolean data = true;
                List<TaskUserInfoEntity> listTaskInfoDaily = taskUserInfoService.list(new QueryWrapper<TaskUserInfoEntity>()
                        .eq("task_code", code).eq("date", toDate).eq("uid", uid));
                for (TaskUserInfoEntity hyTaskUserInfo : listTaskInfoDaily) {
                    if (hyTaskUserInfo.getSid().equals(sid)) {
                        data = false;
                    }
                }
                if (listTaskInfoDaily.size() < hyTask.getTotal() && data) {
                    //获取奖励
                    Map<String, Integer> rewardByCode = this.getRewardByCode(code, uid, null);
                    //发送积分系统和推送
                    this.sendCoin(user,hyTask,rewardByCode);
                    //保存任务记录
                    this.updateInfo(code, sid, user,rewardByCode);
                }else {
                    throw new ServiceException("任务已全部完成/同一资源无法再完成");
                }
            }else {
                throw new ServiceException("任务找不到/未上架");
            }
        }catch (ServiceException e){
            throw new ServiceException(e.getMessage());
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 高阶任务
     * @param uid
     * @param price
     * @param code
     * @return
     * @throws Exception
     */
    public Integer taskSenior(Long uid, Integer price, Integer code) throws Exception {
        User user = userService.getById(uid);
        List<TaskRewardEntity> rewardByCode =
                taskRewardService.findHyTaskRewardByCode(code);
        if(CollUtil.isEmpty(rewardByCode)){
            throw new Exception("任务未设置奖励");
        }
        //判断基数是否小于最小值，小于最小值不执行
        TaskEntity taskByCode = this.baseMapper.selectOne(new QueryWrapper<TaskEntity>()
                .eq("code", code).eq("status", 1));
        if ((ObjectUtil.isNotEmpty(taskByCode)) && (
                (code == FrogxTaskCode.TaskCode.BUY_COURSE && price > taskByCode.getMinBaseNum()) ||
                        (code == FrogxTaskCode.TaskCode.RETAIL_COURSE && price > taskByCode.getMinBaseNum()) ||
                        (code == FrogxTaskCode.TaskCode.RECHAREG && price > taskByCode.getMinBaseNum()) ||
                        (code == FrogxTaskCode.TaskCode.BUY_LIVE && price > taskByCode.getMinBaseNum()) ||
                        (code == FrogxTaskCode.TaskCode.SEND_GIFT && price > taskByCode.getMinBaseNum()))) {
            //判断奖项是否大于0
            if (rewardByCode.size() > 0) {
                //查询奖励
                Map<String, Integer> reward = this.getRewardByCode(code, uid, price);
                int registerScore = reward.get("registerScore");
                try {
                    // 5.完成任务
                    TaskUserInfoEntity hyTaskUserInfo = new TaskUserInfoEntity();
                    // 2.给用户处理积分余额
                    hyTaskUserInfo.setUid(uid);
                    hyTaskUserInfo.setRewardId(reward.get("rewardId"));
                    hyTaskUserInfo.setTaskId(rewardByCode.get(0).getTid());
                    hyTaskUserInfo.setTaskType(FrogxTaskCode.TaskType.SENIOR);
                    hyTaskUserInfo.setCommitTime(new Date());
                    hyTaskUserInfo.setRewordScore(registerScore);
                    hyTaskUserInfo.setTaskCode(taskByCode.getCode());
                    hyTaskUserInfo.setRemark(taskByCode.getName()+"赠送手机号" + user.getPhone());
                    //发送积分系统
                    this.sendCoin(user,taskByCode,reward);
                    taskUserInfoService.UserInfoSave(hyTaskUserInfo);
                    if(code.equals(FrogxTaskCode.TaskCode.RETAIL_COURSE)){
                        return registerScore;
                    }
                } catch (Exception e) {
                    throw new Exception(e.getMessage());
                }
            }
        }
        return null;
    }

    /**
     * 会议任务
     * @param uid
     * @param code
     * @param meetingId
     * @throws Exception
     */
    @Override
    public void taskMeeting(Long uid, Integer code, Integer meetingId) throws Exception {

    }

    /**
     * 签到任务
     *
     * @param uid
     * @param code
     * @param score
     * @throws Exception
     */
    public void addSignScore(Long uid, Integer code, Integer score) throws Exception {
        // 计算当前时间的年月日
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String toDate = sdf.format(new Date());
        User user = userService.getById(uid);
        // 1.查该任务能完成几次
        TaskEntity hyTask = this.baseMapper.selectOne(new QueryWrapper<TaskEntity>()
                .eq("code", code).eq("status", 1));
        if (ObjectUtil.isNotEmpty(hyTask)) {
            if (ObjectUtil.isNotEmpty(hyTask)) {
                //已经完成几次
                //需要不同的资源
                List<TaskUserInfoEntity> listTaskInfoDaily = taskUserInfoService.list(new QueryWrapper<TaskUserInfoEntity>()
                        .eq("task_code", code).eq("date", toDate).eq("uid", uid));
                if (listTaskInfoDaily.size() < hyTask.getTotal()) {
                    Map<String,Integer> reward = new HashMap<>();
                    reward.put("rewardId",0);
                    reward.put("registerScore",score);
                    try {
                        //发送积分系统和推送
                        this.sendCoin(user,hyTask,reward);
                        //保存任务记录
                        this.updateInfo(code,null,user,reward);
                    } catch (Exception e) {
                        throw new Exception(e.getMessage());
                    }
                }
            }

        }
    }

    @Override
    public Integer selectMaxCoinByCode(Integer code) {
        Integer integer = this.baseMapper.selectMaxCoinByCode(code);
        return integer;
    }

    /**
     * 添加记录
     * @param code
     * @param sid  资源id
     * @param user
     * @throws Exception
     */
    public void updateInfo(Integer code, Integer sid, User user,Map<String, Integer> rewardByCode) throws Exception {
        try {
            TaskEntity taskEntity = this.getOne(new QueryWrapper<TaskEntity>().eq("code", code));
            TaskUserInfoEntity hyTaskUserInfo = new TaskUserInfoEntity();
            // 2.给用户处理积分余额
            hyTaskUserInfo.setUid(user.getUid());
            hyTaskUserInfo.setRewardId(rewardByCode.get("rewardId"));
            hyTaskUserInfo.setTaskId(taskEntity.getId());
            hyTaskUserInfo.setTaskType(FrogxTaskCode.TaskType.DAILY);
            hyTaskUserInfo.setStatus(FrogxTaskCode.TaskStatus.RECEIVE);
            hyTaskUserInfo.setCommitTime(new Date());
            hyTaskUserInfo.setRewordScore(rewardByCode.get("registerScore"));
            hyTaskUserInfo.setTaskCode(taskEntity.getCode());
            hyTaskUserInfo.setSid(sid);
            hyTaskUserInfo.setRemark(taskEntity.getName()+"赠送的手机号" + user.getPhone());
            taskUserInfoService.UserInfoSave(hyTaskUserInfo);
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    /**
     *
     * 发送积分系统和推送
     * @param user
     * @param taskEntity
     * @param rewardByCode
     * @throws Exception
     */
    public void sendCoin(User user,TaskEntity taskEntity,Map<String,Integer> rewardByCode) throws Exception{
        try {
            //打包积分系统包体
            CoinDetailEntity coin = new CoinDetailEntity();
            coin.setCoin(Long.valueOf(rewardByCode.get("registerScore")));
            coin.setDesc("完成"+taskEntity.getName());
            coin.setMark(taskEntity.getName());
            coin.setNickname(user.getUsername());
            coin.setTerminal("sever");
            coin.setType("获得");
            umengService.coinPush(user.getUid(), rewardByCode.get("registerScore"), taskEntity.getCode());
            // 3.获取该用户token
            String coinToken = ScoreCoinUtils.getToken(user.getPhone());
            // 4.发送包体至积分项目[userId + channelCode(积分系统通过token直接获取) + CoinDetailEntity]
            ScoreCoinUtils.sendPackage(coin, coinToken);
        }catch (Exception e){
            throw new Exception(e.getMessage());
        }

    }

    /**
     * 获取积分奖励
     * @return
     */
    public Map<String,Integer> getRewardByCode(Integer code, Long uid, Integer price) throws Exception{
        Map<String,Integer> map = new HashMap<>();
        Integer registerScore = 0;
        Integer rewardId = 0;
        List<TaskRewardEntity> rewardByCode = taskRewardService.findHyTaskRewardByCode(code);
        if(CollUtil.isEmpty(rewardByCode)){
            throw new Exception("任务未设置奖励");
        }
        if (rewardByCode.size() > 0) {
            TaskRewardEntity hyTaskReward = null;
            if (rewardByCode.size() == 1) {
                if (rewardByCode.get(0).getType() == 2) {
                    Integer score = rewardByCode.get(0).getScale();
                    Double register = (double) score * 0.01;
                    registerScore = (int) Math.round(register * price);
                } else {
                    registerScore = rewardByCode.get(0).getScore();
                }
                rewardId = rewardByCode.get(0).getId();
            } else {
                // 往随机池里取出一项
                hyTaskReward = TaskRewardUtils.getRewardSingle(rewardByCode, taskUserInfoService, Convert.toInt(uid));
                if (hyTaskReward.getType() == 2) {
                    Integer scale = hyTaskReward.getScale();
                    Double register = (double) scale * 0.01;
                    registerScore = (int) Math.round(register * price);

                } else {
                    registerScore = hyTaskReward.getScore();
                }
                rewardId = hyTaskReward.getId();
            }
        }
        map.put("registerScore",registerScore);
        map.put("rewardId",rewardId);
        return map;
    }



    /**
     * （活动）充值送积分任务
     * @param uid
     * @throws Exception
     */
    public void recharegTask(Long uid, BigDecimal price, Integer code) throws Exception{
        User user = userService.getOne(new QueryWrapper<User>().eq("uid",uid));
        //判断基数是否小于最小值，小于最小值不执行
        TaskRewardEntity sendScoreByMoney = taskRewardService.getSendScoreByMoney(price);
        TaskEntity taskByCode = this.getOne(new QueryWrapper<TaskEntity>().eq("code",code));
        if(taskByCode != null && code == FrogxTaskCode.TaskCode.ACTIVITY_RECHAREG){
            if(sendScoreByMoney == null){
                return;
            }
            int registerScore = 0;
            if(sendScoreByMoney.getScore()!=null){
                registerScore = sendScoreByMoney.getScore();
            }
            // 5.完成任务
            TaskUserInfoEntity hyTaskUserInfo = new TaskUserInfoEntity();
            //判断奖项是否大于0
            try {
                hyTaskUserInfo.setUid(uid);
                hyTaskUserInfo.setRewardId(sendScoreByMoney.getId());
                hyTaskUserInfo.setTaskId(taskByCode.getId());
                hyTaskUserInfo.setTaskType(FrogxTaskCode.TaskType.SENIOR);
                hyTaskUserInfo.setCommitTime(new Date());
                hyTaskUserInfo.setRewordScore(registerScore);

                // 3.发送订单到积分中间系统
                CoinDetailEntity coin = new CoinDetailEntity();
                coin.setCoin(Long.valueOf(registerScore));
                if(code == FrogxTaskCode.TaskCode.ACTIVITY_RECHAREG){
                    coin.setDesc("完成(活动)充值蛙豆任务");
                    coin.setMark("(活动)充值蛙豆");
                    hyTaskUserInfo.setTaskCode(FrogxTaskCode.TaskCode.ACTIVITY_RECHAREG);
                    hyTaskUserInfo.setRemark("(活动)充值蛙豆赠送手机号" + user.getPhone());
                }
                coin.setNickname(user.getUsername());
                coin.setTerminal("sever");
                coin.setType("获得");
                // 3.获取该用户token
                String coinToken = ScoreCoinUtils.getToken(user.getPhone());
                // 4.发送包体至积分项目[userId + channelCode(积分系统通过token直接获取) + CoinDetailEntity]
                ScoreCoinUtils.sendPackage(coin, coinToken);
                taskUserInfoService.UserInfoSave(hyTaskUserInfo);
                System.out.println("执行任务完毕");
                umengService.coinPush( uid, registerScore,code);
            } catch (Exception e) {
                throw new Exception(e.getMessage());
            }
        }

    }


}
